﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ARMIR.util;
using RimWorld;
using RimWorld.Planet;
using UnityEngine;
using Verse;
using static RimWorld.ColonistBar;
using static UnityEngine.GraphicsBuffer;

namespace ARMIR
{
    public class HediffComp_mindMeleeAttack : HediffComp {
        public HediffCompProperties_mindMeleeAttack Props => (HediffCompProperties_mindMeleeAttack)props;

        private int gapMelee;
        public int meleeEEE;

        public override void CompPostMake()
        {
            base.CompPostMake();
            gapMelee = 0;
            meleeEEE = 0;
        }

        public override void CompPostTick(ref float severityAdjustment)
        {
            base.CompPostTick(ref severityAdjustment);
            if (gapMelee > Props.gapAttack) {
                doMindMeleeAttack();
            }else {
                gapMelee++;
            }
        }

        private void doMindMeleeAttack() {
            //检查是否正在攻击敌人
            var pawnAttack = parent.pawn.meleeVerbs.TryGetMeleeVerb(parent.pawn);
            LocalTargetInfo meleeTarget = null;
            if (pawnAttack != null) {
                meleeTarget = pawnAttack.CurrentTarget;
            }
            if (meleeTarget == null) {
                return;
            }else {
                //Log.Message(meleeTarget);
                if (meleeTarget.Pawn == null) { return; }
                if (meleeTarget.Pawn.Downed || !meleeTarget.Pawn.Spawned) { return; }
                //Log.Message(meleeTarget.Pawn.Position);

                //尝试发起攻击
                if (parent.pawn.Map == null) { return; }
                if (GenSight.LineOfSight(parent.pawn.Position, meleeTarget.Pawn.Position, parent.pawn.Map, skipFirstCell: true)
                && meleeTarget.Pawn.Position.DistanceTo(parent.pawn.Position) < 24
                && !parent.pawn.Downed) {
                    float randomExp = UnityEngine.Random.value;
                    if (randomExp >= 0 && randomExp <= 0.7)
                    {
                        rangeExplosive(meleeTarget.Pawn.Position);
                    }
                    else if (randomExp <= 1 && randomExp > 0.8)
                    {
                        lineExplosive(meleeTarget.Pawn.Position);
                    }
                    else
                    {
                        lockExplosive(meleeTarget.Pawn.Position);
                    }
                }
            }
        }

        private void rangeExplosive(IntVec3 doPos) {
            // 设置延迟
            TickUtil DelayTick = Current.Game.GetComponent<TickUtil>();


            //float lan = 7;
            //Vector3 effectPos = doPos.ToVector3();
            //effectPos = new Vector3(effectPos.x, effectPos.y, effectPos.z + lan);
            //float dynamicSpeed = 0.1f;
            //int dynamicDelay = 0;
            //for (int i = 0; i < 5; i++)
            //{
            //    DelayTick.TickTimeManager(dynamicDelay, () => {
            //        speDraw.drawBlockBox(parent.pawn.Map, effectPos, Props.radius, Props.radius, -dynamicSpeed, lan);
            //    }, true);
            //    dynamicSpeed = dynamicSpeed + 0.08f;
            //    dynamicDelay = dynamicDelay + 8;
            //}



            //发生爆炸
            List<Thing> ExplosiveIgnoredPawns = new List<Thing>();
            ExplosiveIgnoredPawns = parent.pawn.Map.mapPawns.AllPawnsSpawned.Where(p => p.Faction == Faction.OfPlayer && p.Position.DistanceTo(doPos) < Props.radius + 2).OfType<Thing>().ToList();
            ExplosiveIgnoredPawns.AddRange(parent.pawn.Map.listerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver)).Where(p => p.Position.DistanceTo(doPos) < Props.radius + 2));
            ExplosiveIgnoredPawns.AddRange(parent.pawn.Map.listerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.Corpse)).Where(p => p.Position.DistanceTo(doPos) < Props.radius + 2));
            ExplosiveIgnoredPawns.Add(parent.pawn);

            int powerBase = (int)ARMIR_ModSettings.powerSet;

            bool hasEquipment = parent.pawn != null &&
                                    (parent.pawn.equipment.AllEquipmentListForReading.Any(e =>
                                         e.def == Props.requireEquipment) ||
                                     parent.pawn.apparel.WornApparel.Any(a => a.def == Props.requireEquipment));

            if (hasEquipment) {
                int dynamicDelay = 0;

                for (int i = 0; i < 4; i++) {
                    //speDraw.DragLight(parent.pawn.Map, doPos.ToVector3(), 10, 0.15f, 5, false, false, 0, 0.5f);

                    DelayTick.TickTimeManager(dynamicDelay, () => {

                        EffecterDef TMLandB = DefDatabase<EffecterDef>.GetNamed("ARMIR_meleeAtack_EffecterA"); //特效
                        TMLandB.Spawn(doPos, parent.pawn.Map);

                        useRandomSwordLight(parent.pawn.Position,doPos,parent.pawn.Map);

                        GenExplosion.DoExplosion(
                        doPos,
                        parent.pawn.Map,
                        radius: Props.radius,
                        DamageDefOf.Crush,
                        instigator: parent.pawn,
                        damAmount: (int)(Props.damageAmount * powerBase * Props.materielDamage),
                        armorPenetration: Props.damagePen * powerBase + Props.materielPen,
                        damageFalloff: false, //伤害随距离衰减开启
                        screenShakeFactor: 0.3f, //屏幕震动强度(默认为1
                        explosionSound: DefDatabase<SoundDef>.GetNamed("ARMIR_magicHitA"),
                        ignoredThings: ExplosiveIgnoredPawns
                        );
                    }, true);
                    dynamicDelay = dynamicDelay + 10;
                }

                //重置冷却
                gapMelee = -180;
            }
            else
            {
                EffecterDef TMLandB = DefDatabase<EffecterDef>.GetNamed("ARMIR_meleeAtack_EffecterA"); //特效
                TMLandB.Spawn(doPos, parent.pawn.Map);

                GenExplosion.DoExplosion(
                    doPos,
                    parent.pawn.Map,
                    radius: Props.radius,
                    DamageDefOf.Crush,
                    instigator: parent.pawn,
                    damAmount: Props.damageAmount * powerBase,
                    armorPenetration: Props.damagePen * powerBase,
                    damageFalloff: false, //伤害随距离衰减开启
                    screenShakeFactor: 0.1f, //屏幕震动强度(默认为1
                    explosionSound: DefDatabase<SoundDef>.GetNamed("ARMIR_fakeEmpty"),
                    ignoredThings: ExplosiveIgnoredPawns
                );

                //重置冷却
                gapMelee = 0;
            }
        }

        private void lineExplosive(IntVec3 doPos) {
            // 设置延迟
            TickUtil DelayTick = Current.Game.GetComponent<TickUtil>();

            IntVec3 hapPos = doPos;
            int dir = UnityEngine.Random.Range(-1, 1);
            int zir = UnityEngine.Random.Range(-1, 1);
            int lanE = UnityEngine.Random.Range(1, 7);
            for (int i = 0; i < lanE; i++) {
                EffecterDef TMLandB = DefDatabase<EffecterDef>.GetNamed("ARMIR_meleeAtack_Effecter"); //特效
                TMLandB.Spawn(hapPos, parent.pawn.Map);

                //发生爆炸
                List<Thing> ExplosiveIgnoredPawns = new List<Thing>();
                ExplosiveIgnoredPawns = parent.pawn.Map.mapPawns.AllPawnsSpawned.Where(p => p.Faction == Faction.OfPlayer && p.Position.DistanceTo(doPos) < Props.radius + 2).OfType<Thing>().ToList();
                ExplosiveIgnoredPawns.AddRange(parent.pawn.Map.listerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver)).Where(p => p.Position.DistanceTo(doPos) < Props.radius + 2));
                ExplosiveIgnoredPawns.AddRange(parent.pawn.Map.listerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.Corpse)).Where(p => p.Position.DistanceTo(doPos) < Props.radius + 2));
                ExplosiveIgnoredPawns.Add(parent.pawn);

                int powerBase = (int)ARMIR_ModSettings.powerSet;

                GenExplosion.DoExplosion(
                    hapPos,
                    parent.pawn.Map,
                    radius: 1,
                    DamageDefOf.Crush,
                    instigator: parent.pawn,
                    damAmount: Props.damageAmount * powerBase * 2,
                    armorPenetration: Props.damagePen * powerBase * 2,
                    damageFalloff: false, //伤害随距离衰减开启
                    screenShakeFactor: 0.1f, //屏幕震动强度(默认为1
                    explosionSound: DefDatabase<SoundDef>.GetNamed("ARMIR_fakeEmpty"),
                    ignoredThings: ExplosiveIgnoredPawns
                );

                //迭代坐标
                hapPos = new IntVec3(hapPos.x + dir, hapPos.y, hapPos.z + zir);
            }

            //重置冷却
            gapMelee = 80;
        }

        private void lockExplosive(IntVec3 doPos) {
            // 设置延迟
            TickUtil DelayTick = Current.Game.GetComponent<TickUtil>();

            var enemies = parent.pawn.Map.mapPawns.AllPawnsSpawned.Where(p => p.HostileTo(parent.pawn)
            && p.Position.DistanceTo(doPos) < 5
            && !p.Downed).ToList();

            int dynamicDelayEn = 0;

            bool hasEquipment = parent.pawn != null &&
                                    (parent.pawn.equipment.AllEquipmentListForReading.Any(e =>
                                         e.def == Props.requireEquipment) ||
                                     parent.pawn.apparel.WornApparel.Any(a => a.def == Props.requireEquipment));

            foreach (var enemy in enemies) {
                DelayTick.TickTimeManager(dynamicDelayEn, () => {
                    EffecterDef TMLandB = DefDatabase<EffecterDef>.GetNamed("ARMIR_meleeAtack_Effecter"); //特效
                    TMLandB.Spawn(enemy.Position, parent.pawn.Map);



                    //发生爆炸
                    List<Thing> ExplosiveIgnoredPawns = new List<Thing>();
                    ExplosiveIgnoredPawns = parent.pawn.Map.mapPawns.AllPawnsSpawned.Where(p => p.Faction == Faction.OfPlayer && p.Position.DistanceTo(enemy.Position) < Props.radius + 2).OfType<Thing>().ToList();
                    ExplosiveIgnoredPawns.AddRange(parent.pawn.Map.listerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver)).Where(p => p.Position.DistanceTo(enemy.Position) < Props.radius + 2));
                    ExplosiveIgnoredPawns.AddRange(parent.pawn.Map.listerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.Corpse)).Where(p => p.Position.DistanceTo(enemy.Position) < Props.radius + 2));
                    ExplosiveIgnoredPawns.Add(parent.pawn);

                    int powerBase = (int)ARMIR_ModSettings.powerSet;

                    if (hasEquipment)
                    {
                        useRandomSwordLight(parent.pawn.Position, enemy.Position, parent.pawn.Map);

                        GenExplosion.DoExplosion(
                            enemy.Position,
                            parent.pawn.Map,
                            radius: 1,
                            DamageDefOf.Crush,
                            instigator: parent.pawn,
                            damAmount: (int)(Props.damageAmount * powerBase * 0.5f / Props.materielDamage),
                            armorPenetration: Props.damagePen * powerBase + 0.4f + Props.materielPen,
                            damageFalloff: false, //伤害随距离衰减开启
                            screenShakeFactor: 0.1f, //屏幕震动强度(默认为1
                            explosionSound: DefDatabase<SoundDef>.GetNamed("ARMIR_fakeEmpty"),
                            ignoredThings: ExplosiveIgnoredPawns
                        );
                    }
                    else {
                        GenExplosion.DoExplosion(
                            enemy.Position,
                            parent.pawn.Map,
                            radius: 1,
                            DamageDefOf.Crush,
                            instigator: parent.pawn,
                            damAmount: (int)(Props.damageAmount * powerBase * 0.5f),
                            armorPenetration: Props.damagePen * powerBase + 0.4f,
                            damageFalloff: false, //伤害随距离衰减开启
                            screenShakeFactor: 0.1f, //屏幕震动强度(默认为1
                            explosionSound: DefDatabase<SoundDef>.GetNamed("ARMIR_fakeEmpty"),
                            ignoredThings: ExplosiveIgnoredPawns
                        );
                    }
                }, true);
                dynamicDelayEn = dynamicDelayEn + 5;
            }
            //重置冷却
            if (hasEquipment) {
                gapMelee = -300;
            }else {
                gapMelee = -100;
            }
            
        }

        private void useRandomSwordLight(IntVec3 dot,IntVec3 doPos, Map map) {
            EffecterDef TMLandA = DefDatabase<EffecterDef>.GetNamed("ARMIR_swordLight_EffecterA"); //特效
            EffecterDef TMLandB = DefDatabase<EffecterDef>.GetNamed("ARMIR_swordLight_EffecterB"); //特效
            EffecterDef TMLandC = DefDatabase<EffecterDef>.GetNamed("ARMIR_swordLight_EffecterC"); //特效
           
            Effecter effecter = null;

            if (meleeEEE == 0)
            {
                effecter = TMLandA.Spawn();
                meleeEEE++;
            }
            else if (meleeEEE == 1)
            {
                effecter = TMLandB.Spawn();
                meleeEEE++;
            }
            else {
                effecter = TMLandC.Spawn();
                meleeEEE = 0;
            }

            if (effecter != null) {
                TargetInfo TargetInfoA = new TargetInfo(dot, map);
                TargetInfo TargetInfoB = new TargetInfo(doPos, map);
                effecter.Trigger(TargetInfoA, TargetInfoB);
            }
        }
    }
}
